using System;
using Headspring.Training.Core.Model;
using Headspring.Training.Core.Model.StateCommands;
using Headspring.Training.Core.Services;
using Headspring.Training.Core.Services.Impl;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using Rhino.Mocks;

namespace Headspring.Training.UnitTests.Services
{
	[TestFixture]
	public class WorkflowFacilitatorTester
	{
		public class StubbedStateCommand : IStateCommand
		{
			private readonly bool _isValid;

			public StubbedStateCommand(bool isValid)
			{
				_isValid = isValid;
			}

			public bool IsValid()
			{
				return _isValid;
			}

			public void Execute(IStateCommandVisitor commandVisitor)
			{
				throw new NotImplementedException();
			}

			public string TransitionVerbPresentTense
			{
				get { throw new NotImplementedException(); }
			}

			public bool Matches(string commandName)
			{
				throw new NotImplementedException();
			}

			public WorkOrderStatus GetBeginStatus()
			{
				throw new NotImplementedException();
			}
		}

		[Test]
		public void ShouldFilterFullListToReturnValidCommands()
		{
			var mocks = new MockRepository();
			var facilitator = mocks.PartialMock<WorkflowFacilitator>(null, null);
			var commandsToReturn = new IStateCommand[]
			                       	{
			                       		new StubbedStateCommand(true),
			                       		new StubbedStateCommand(true),
			                       		new StubbedStateCommand(false)
			                       	};

			Expect.Call(facilitator.GetAllStateCommands(null, null)).IgnoreArguments().
				Return(commandsToReturn);
			mocks.ReplayAll();

			IStateCommand[] commands = facilitator.GetValidStateCommands(null, null);

			mocks.VerifyAll();
			Assert.That(commands.Length, Is.EqualTo(2));
		}

		[Test]
		public void ShouldGetNoValidStateCommandsForWrongUser()
		{
			var facilitator =
				new WorkflowFacilitator(new StubbedCalendar(new DateTime(2000, 1, 1)), null);
			var workOrder = new WorkOrder();
			var employee = new Employee();
			IStateCommand[] commands = facilitator.GetValidStateCommands(workOrder,
			                                                             employee);

			Assert.That(commands.Length, Is.EqualTo(0));
		}


		[Test]
		public void ShouldReturnAllStateCommandsInCorrectOrder()
		{
			var facilitator =
				new WorkflowFacilitator(new StubbedCalendar(new DateTime(2000, 1, 1)), null);
			IStateCommand[] commands = facilitator.GetAllStateCommands(new WorkOrder(),
			                                                           new Employee());

			Assert.That(commands.Length, Is.EqualTo(11));
			Assert.That(commands[0], Is.InstanceOfType(typeof (SaveDraftCommand)));
			Assert.That(commands[1], Is.InstanceOfType(typeof (DraftToAssignedCommand)));
			Assert.That(commands[2],
			            Is.InstanceOfType(typeof (AssignedToInProgressCommand)));
			Assert.That(commands[3], Is.InstanceOfType(typeof (AssignedToDraftCommand)));
			Assert.That(commands[4],
			            Is.InstanceOfType(typeof (InProgressToAssignedCommand)));
			Assert.That(commands[5],
			            Is.InstanceOfType(typeof (InProgressToCompleteCommand)));
			Assert.That(commands[6],
			            Is.InstanceOfType(typeof (CompleteToAssignedCommand)));
			Assert.That(commands[7], Is.InstanceOfType(typeof (DraftToCancelledCommand)));
			Assert.That(commands[8],
			            Is.InstanceOfType(typeof (AssignedToCancelledCommand)));
			Assert.That(commands[9],
			            Is.InstanceOfType(typeof (InProgressToCancelledCommand)));
			Assert.That(commands[10],
			            Is.InstanceOfType(typeof (CompleteToCancelledCommand)));
		}
	}
}